package com.mijie.homi.api;

import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.mijie.core.Status;
import com.mijie.exception.RecordNotFoundException;
import com.mijie.homi.common.constant.HomiConstants;
import com.mijie.homi.common.constant.HomiStatusCode;
import com.mijie.homi.common.domain.SearchResult;
import com.mijie.homi.common.domain.mood.Mood;
import com.mijie.homi.common.domain.topic.RelatedTopic;
import com.mijie.homi.common.domain.topic.Topic;
import com.mijie.homi.common.domain.topic.TopicType;
import com.mijie.homi.common.domain.user.User;
import com.mijie.homi.common.domain.user.UserExtInfo;
import com.mijie.homi.common.util.HomiUtil;
import com.mijie.homi.domain.commom.Review;
import com.mijie.homi.domain.topic.ConsensusUser;
import com.mijie.homi.domain.topic.TopicOpinion;
import com.mijie.homi.domain.topic.TopicOptions;
import com.mijie.homi.service.common.CommentService.COMMENT;
import com.mijie.homi.service.common.ReplyService.REPLY;
import com.mijie.homi.service.mood.MoodService;
import com.mijie.homi.service.topic.TopicService;
import com.mijie.homi.service.user.FriendService;
import com.mijie.homi.service.user.UserExtInfoService;
import com.mijie.homi.service.user.UserService;
import com.mijie.homi.util.ServerHelper;
import com.mijie.util.GeoUtil;
import com.mijie.util.IOUtil;

@Controller
@RequestMapping("/topic")
public class TopicApi extends CommomApi{

	@Autowired
	private TopicService topicService;
	@Autowired
	private UserExtInfoService extInfoService;
	@Autowired
	private UserService userService;
	@Autowired
	private MoodService moodService;
	@Autowired
	private FriendService friendService;
	
	private static Logger logger = Logger.getLogger(TopicApi.class);
	
	private static final int TOPIC_TYPE_TOP = 1;
	private static final int TOPIC_TYPE_NEW = 2;
	private static final int TOPIC_TYPE_ACTIVE = 3;
	private static final int TOPIC_TYPE_HOT = 4;
	private static final int TOPIC_TYPE_MATCH = 5;
	
	@RequestMapping(value="/list",method=RequestMethod.GET)
	public @ResponseBody void list(int type,Long pointInTime,int offset,int limit,
			HttpServletRequest request,HttpServletResponse response){
		if(offset<=0) pointInTime = null;
		Status status = new Status(request,response);
		Date startTime = null;
		if(pointInTime==null) startTime = new Date();
		else startTime = new Date(pointInTime);
		List<Integer> list = topicService.listTopicIdByType(type, startTime, offset, limit);
		JSONObject result =  new JSONObject();
		JSONArray topicArray =  JSONArray.fromObject(list);
		Integer userId = ServerHelper.getUserId(request);
		toJSONArray(userId,topicArray, true);
		result.accumulate("pointInTime", startTime.getTime());
		result.accumulate("list", topicArray);
		status.setResult(result);
		status.write();
	}
	
	@RequestMapping(value="/list/tag",method=RequestMethod.GET)
	public @ResponseBody void listTag(HttpServletRequest request,HttpServletResponse response){
		Integer userId = ServerHelper.getUserId(request);
		Status status = new Status(request,response);
		String tags = topicService.getTopicTagForUser(userId);
		if(tags==null) tags = "[]";
		status.setResult(tags);
		status.write();
	}
	
	@RequestMapping(value="/list/category",method=RequestMethod.GET)
	public @ResponseBody void listCategory(HttpServletRequest request,HttpServletResponse response){
		Integer userId = ServerHelper.getUserId(request);
		Status status = new Status(request,response);
		List<TopicType> list = topicService.listTopicType();
		JSONArray result = new JSONArray();
		JSONObject json = null;
		List<Topic> topicList = null;
		JSONArray topicJsonArray = null;
		HashSet<Integer> bucket = new HashSet<Integer>();
		long s = System.currentTimeMillis();
		int MAX_RECORD = 5;
		int offset = 0;
		int pageSize = 15;
		JSONObject topicJson = null;
		for(TopicType type : list){
			json = new JSONObject();
			json.accumulate("id", type.getId());
			json.accumulate("name", type.getName());
			json.accumulate("describes", type.getDescribes());
			json.accumulate("icon", HomiUtil.getRealUrl(type.getIcon()));
			json.accumulate("image", HomiUtil.getRealUrl(type.getImage()));
			topicJsonArray = new JSONArray();
			offset = 0;
			while(true){
				topicList = topicService.fetchTopicByType(type.getId(), offset, pageSize);
				offset += pageSize;
				if(topicList.isEmpty()){
					break;
				}else{
					for(Topic topic : topicList){
						if(bucket.contains(topic.getId())) continue;
						topicJson = new JSONObject();
						topicJson.accumulate("title", topic.getTitle());
						topicJsonArray.add(topicJson);
						bucket.add(topic.getId());
						if(topicJsonArray.size()>=MAX_RECORD) break;
					}
					if(topicJsonArray.size()>=MAX_RECORD || topicList.size()<pageSize) break;
				}
			}
			
			json.accumulate("topicList", topicJsonArray);
			result.add(json);
		}
		long e = System.currentTimeMillis();
		bucket = null;
		status.setResult(result);
		status.write();
	}
	
	@RequestMapping(value="/list/top",method=RequestMethod.GET)
	public @ResponseBody void listTopicOfTop(String idxf,int offset,int limit,
			HttpServletRequest request,HttpServletResponse response) throws Exception{
		searchTopic(idxf,TOPIC_TYPE_TOP,offset,limit,request,response);
	}
	
	@RequestMapping(value="/list/hot",method=RequestMethod.GET)
	public @ResponseBody void listTopicOfHot(String idxf,int offset,int limit,
			HttpServletRequest request,HttpServletResponse response) throws Exception{
		searchTopic(idxf,TOPIC_TYPE_HOT,offset,limit,request,response);
	}
	
	@RequestMapping(value="/list/new",method=RequestMethod.GET)
	public @ResponseBody void listTopicOfNew(String idxf,int offset,int limit,
			HttpServletRequest request,HttpServletResponse response) throws Exception{
		searchTopic(idxf,TOPIC_TYPE_NEW,offset,limit,request,response);
	}
	
	@RequestMapping(value="/list/active",method=RequestMethod.GET)
	public @ResponseBody void listTopicOfActive(String idxf,int offset,int limit,
			HttpServletRequest request,HttpServletResponse response) throws Exception{
		searchTopic(idxf,TOPIC_TYPE_ACTIVE,offset,limit,request,response);
	}
	
	@RequestMapping(value="/list/match",method=RequestMethod.GET)
	public @ResponseBody void listTopicOfMatch(String idxf,int offset,int limit,
			HttpServletRequest request,HttpServletResponse response) throws Exception{
		searchTopic(idxf,TOPIC_TYPE_MATCH,offset,limit,request,response);
	}
	
	
	@RequestMapping(value="/search",method=RequestMethod.GET)
	public @ResponseBody void search(String idxf,String keyword,int offset,int limit,
			HttpServletRequest request,HttpServletResponse response) throws Exception{
		Integer userId = ServerHelper.getUserId(request);
		Status status = new Status(request,response);
		SearchResult result = topicService.searchByKeyword(idxf, keyword, offset, limit);
		toJSONArray(userId,result.getResult(),true);
		status.setResult(result.getResult());
		status.write();
	}
	
	private void searchTopic(String idxf,int type,int offset,int limit,
			HttpServletRequest request,HttpServletResponse response) throws Exception{
		Integer userId = ServerHelper.getUserId(request);
		Status status = new Status(request,response);
		UserExtInfo info = extInfoService.getUserExtInfoByUserId(userId);
		SearchResult result = null;
		if(info!=null){
			boolean countRealyParticipate = true;
			switch(type){
			case TOPIC_TYPE_TOP :
				result = topicService.listTopicOfTop(idxf,info.getMood(), offset, limit);
				break;
			case TOPIC_TYPE_NEW:
				result = topicService.listTopicOfNew(idxf,info.getMood(), offset, limit);
				break;
			case TOPIC_TYPE_ACTIVE:
				result = topicService.listTopicOfActive(idxf,info.getMood(), offset, limit);
				break;
			case TOPIC_TYPE_HOT:
				countRealyParticipate = false; 
				result = topicService.listTopicOfHot(idxf,info.getMood(), offset, limit);
				break;
			case TOPIC_TYPE_MATCH:
				result = topicService.listTopicOfMatch(idxf,userId, offset, limit);
				break;
			default : throw new Exception();
			}
			toJSONArray(userId,result.getResult(),countRealyParticipate);
			status.setResult(result.getResult());
			if(result.getCode()==SearchResult.INDEX_EXPIRE)
				status.setCode(HomiStatusCode.UNSATISFIED);
		}
		status.write();
	}
	
	private void toJSONArray(Integer requester,JSONArray result,boolean countRealyParticipate){
		if(result!=null &&!result.isEmpty()){
			JSONObject json = null;
			Topic topic = null;
			User author = null;
			for(int i=0;i<result.size();i++){
				json = result.getJSONObject(i);
				topic = topicService.getTopicById(json.getInt("id"));
				author = userService.getUserById(topic.getAuthor());
				json.put("title", topic.getTitle());
				json.put("author", 0);
				json.put("authorGender", 0);
				json.put("authorNickName", "无名");
				json.put("authorAvatar", "");
				json.put("timelineId", topic.getTimelineId());
				json.put("anonymous", topic.getAnonymous());
				
				if(author!=null){
					json.put("author", author.getId());
					json.put("authorGender", author.getGender());
					json.put("authorNickName", author.getNickName());
					json.put("authorAvatar", HomiUtil.getRealUrl(author.getAvatar()));
				}
				json.put("numOfOpinion", topic.getNumOfOpinion());
				json.put("numOfConfused", topic.getNumOfConfused());
				if(countRealyParticipate)
					json.put("numOfParticipate", topic.getNumOfParticipate());
				
				Integer optionId = null;
				if(requester!=null)
					optionId = topicService.getChoicedOptionIdByUserIdAndTopicId(requester, topic.getId());
				json.accumulate("optionIdOfMineChoice", optionId==null?0:optionId);
				
				List<TopicOptions> optionsList = topicService.getOptions(topic.getId());
				JSONArray options = JSONArray.fromObject(optionsList);
				json.accumulate("options", options);
			}
		}
	}
	
	@RequestMapping(value="/post",method=RequestMethod.POST)
	public @ResponseBody void postTopic(HttpServletRequest request,HttpServletResponse response) throws Exception{
		Status status = new Status(request,response);
		String content = IOUtil.getContent4InputStream(request.getInputStream());
		JSONObject json = JSONObject.fromObject(content);
		JSONArray options = json.getJSONArray("options");
		
		if(options.size()>6){
			status.setCode(HomiStatusCode.API_EXCEPTION);
			status.write();
			return;
		}
		String choice = "";
		if(json.containsKey("choice"))
			choice = json.getString("choice");
		
		
		Integer userId = ServerHelper.getUserId(request);
		
		Topic topic = new Topic();
		topic.setTitle(json.getString("title"));
		
		if(json.containsKey("tag"))
			topic.setTag(json.getString("tag"));
		else topic.setTag("");
		
		topic.setAuthor(userId);
		topic.setCreateAt(new Date());
		String[] optionArray = new String[options.size()];
		for(int i=0;i<options.size();i++){
			optionArray[i] = options.getString(i);
		}
		List<TopicOptions> optionsList = topicService.postTopic(topic,optionArray,choice);
		if(optionsList!=null){
			JSONObject result = new JSONObject();
			result.accumulate("id", topic.getId());
			result.accumulate("timelineId", topic.getTimelineId());
			options = JSONArray.fromObject(optionsList);
			result.accumulate("options", options);
			status.setResult(result);
		}else{
			status.setCode(HomiStatusCode.API_EXCEPTION);
		}
		status.write();
	}
	
	@RequestMapping(value="/get_by_opinion",method=RequestMethod.GET)
	public @ResponseBody void getTopicByOpinion(long id,HttpServletRequest request,HttpServletResponse response) throws IOException{
		TopicOpinion opinion = topicService.getTopicOpinionById(id);
		Status status = new Status(request,response);
		if(opinion!=null){
			Topic topic = topicService.getTopicById(opinion.getTopicId());
			if(topic!=null){
				User author = userService.getUserById(topic.getAuthor());
				JSONObject result = JSONObject.fromObject(topic);
				result.remove("tag");
				result.remove("isTop");
				result.remove("moodType");
				result.put("author", author.getId());
				result.put("authorNickName", author.getNickName());
				result.put("authorAvatar", HomiUtil.getRealUrl(author.getAvatar()));
				result.put("authorGender", author.getGender());
				result.put("createAt", topic.getCreateAt().getTime());
				List<TopicOptions> list = topicService.getOptions(topic.getId());
				JSONArray array = JSONArray.fromObject(list);
				result.accumulate("options", array);
				status.setResult(result);
				list.clear();
				list = null;
			}else{
				status.setCode(HomiStatusCode.RECORD_NOT_FOUND);
			}
		}else{
			status.setCode(HomiStatusCode.RECORD_NOT_FOUND);
		}
		status.write();
	}
	
	@RequestMapping(value="/get",method=RequestMethod.GET)
	public @ResponseBody void getTopic(int id,HttpServletRequest request,HttpServletResponse response)
			throws IOException{
		Topic topic = topicService.getTopicById(id);
		Status status = new Status(request,response);
		if(topic!=null){
			JSONObject result = JSONObject.fromObject(topic);
			result.remove("tag");
			result.remove("isTop");
			result.remove("moodType");
			result.put("createAt", topic.getCreateAt().getTime());
			if(ServerHelper.getUserId(request)==null){
				//3g版页面请求时才需要该字段
				User author = userService.getUserById(topic.getAuthor());
				result.put("authorNickname", author.getNickName());
			}
			List<TopicOptions> list = topicService.getOptions(topic.getId());
			JSONArray array = JSONArray.fromObject(list);
			result.accumulate("options", array);
			Integer optionId = null;
			if(ServerHelper.getUserId(request)!=null)
				optionId = topicService.getChoicedOptionIdByUserIdAndTopicId(ServerHelper.getUserId(request), id);
			result.accumulate("optionIdOfMineChoice", optionId==null?0:optionId);
			status.setResult(result);
			list.clear();
			list = null;
		}else{
			status.setCode(HomiStatusCode.RECORD_NOT_FOUND);
		}
		status.write();
	}
	
	
	@RequestMapping(value="/confused",method=RequestMethod.POST)
	public @ResponseBody void confused(HttpServletRequest request,HttpServletResponse response) throws IOException{
		String content = IOUtil.getContent4InputStream(request.getInputStream());
		JSONObject json = JSONObject.fromObject(content);
		Status status = new Status(request,response);
		try {
			topicService.incrNumOfConfused(json.getInt("id"),ServerHelper.getUserId(request));
		} catch (RecordNotFoundException e) {
			logger.error(e.getMessage(), e);
			status.setCode(HomiStatusCode.RECORD_NOT_FOUND);
		}
		status.write();
	}
	
	@RequestMapping(value="/confused/cancel",method=RequestMethod.POST)
	public @ResponseBody void confusedCancel(HttpServletRequest request,HttpServletResponse response) throws IOException{
		String content = IOUtil.getContent4InputStream(request.getInputStream());
		JSONObject json = JSONObject.fromObject(content);
		Status status = new Status(request,response);
		topicService.decrNumOfConfused(json.getInt("id"),ServerHelper.getUserId(request));
		status.write();
	}
	
	@RequestMapping(value="/confused/users",method=RequestMethod.GET)
	public @ResponseBody void confusedUsers(int id,int limit,HttpServletRequest request,HttpServletResponse response) throws IOException{
		Topic topic = topicService.getTopicById(id);
		Status status = new Status(request,response);
		if(topic==null){
			status.setCode(HomiStatusCode.RECORD_NOT_FOUND);
			status.write();
			return;
		}
		
		List<User> list = topicService.listTopicConfused(id, limit);
		JSONObject result = new JSONObject();
		JSONArray users = new JSONArray();
		JSONObject json = null;
		for(User user : list){
			json = new JSONObject();
			json.accumulate("id", user.getId());
			json.accumulate("gender", user.getGender());
			json.accumulate("avatar", HomiUtil.getRealUrl(user.getAvatar()));
			users.add(json);
		}
		result.accumulate("count", topic.getNumOfConfused());
		result.accumulate("users", users);
		status.setResult(result);
		status.write();
	}
	
	@RequestMapping(value="/list/related",method=RequestMethod.GET)
	public @ResponseBody void listRelatedTopic(int userId,int offset,int limit,
			HttpServletRequest request,HttpServletResponse response) throws Exception{
		List<RelatedTopic> list = topicService.listRelatedTopic(userId, offset, limit);
		JSONArray result = new JSONArray();
		Status status = new Status(request,response);
		Topic topic = null;
		JSONObject json = null;
		User author = null;
		RelatedTopic related = null;
		Iterator<RelatedTopic> iter = list.iterator();
		while(iter.hasNext()){
			related = iter.next();
			iter.remove();
			json = new JSONObject();
			topic = topicService.getTopicById(related.getTopicId());
			if(topic==null) continue;
			author = userService.getUserById(topic.getAuthor());
			json.put("authorAvatar", "");
			if(author!=null)
				json.put("authorAvatar", HomiUtil.getRealUrl(author.getAvatar()));
			json.accumulate("author", author==null?0:author.getId());
			json.accumulate("own", related.getIsOwnTopic());
			json.accumulate("optionId", related.getOptionId());
			json.accumulate("id", related.getTopicId());
			json.accumulate("options", related.getOptions());
			json.accumulate("title", topic.getTitle());
			json.accumulate("numOfOpinion", topic.getNumOfOpinion());
			json.accumulate("numOfParticipate", topic.getNumOfParticipate());
			result.add(json.toString());
		}
		iter = null;
		list = null;
		status.setResult(result);
		status.write();
	}
	
	@RequestMapping(value="/list/related_to_me",method=RequestMethod.GET)
	public @ResponseBody void listRelatedToMeTopic(int userId,int offset,int limit,
			HttpServletRequest request,HttpServletResponse response) throws Exception{
		List<RelatedTopic> list = topicService.listRelatedTopic(userId, offset, limit);
		JSONArray result = new JSONArray();
		Status status = new Status(request,response);
		Topic topic = null;
		JSONObject json = null;
		User author = null;
		RelatedTopic related = null;
		Iterator<RelatedTopic> iter = list.iterator();
		while(iter.hasNext()){
			related = iter.next();
			iter.remove();
			json = new JSONObject();
			topic = topicService.getTopicById(related.getTopicId());
			if(topic==null) continue;
			author = userService.getUserById(topic.getAuthor());
			json.put("authorAvatar", "");
			if(author!=null)
				json.put("authorAvatar", HomiUtil.getRealUrl(author.getAvatar()));
			json.accumulate("author", author==null?0:author.getId());
			json.accumulate("own", related.getIsOwnTopic());
			json.accumulate("optionId", related.getOptionId());
			json.accumulate("id", related.getTopicId());
			json.accumulate("optionOfMine",related.getOptions());
			json.accumulate("title", topic.getTitle());
			json.accumulate("numOfOpinion", topic.getNumOfOpinion());
			json.accumulate("numOfParticipate", topic.getNumOfParticipate());
			json.accumulate("numOfConfused", topic.getNumOfConfused());
			List<TopicOptions> options = topicService.getOptions(topic.getId());
			JSONArray array = JSONArray.fromObject(options);
			json.accumulate("options", array);
			result.add(json.toString());
		}
		iter = null;
		list = null;
		status.setResult(result);
		status.write();
	}
	
	
	@RequestMapping(value="/option/choice",method=RequestMethod.POST)
	public @ResponseBody void choiceOption(HttpServletRequest request,HttpServletResponse response) 
			throws IOException{
		String content = IOUtil.getContent4InputStream(request.getInputStream());
		JSONObject json = JSONObject.fromObject(content);
		int topicId = json.getInt("topicId");
		int optionId = json.getInt("optionId");
		int limit = json.getInt("limit");
	
		Integer userId = ServerHelper.getUserId(request);
		
		Status status = new Status(request,response);
		if(!topicService.alreadyChoice(userId, topicId)){
			try {
				int succ = topicService.choiceOption(userId, topicId, optionId);
				if(succ==0)
					status.setCode(HomiStatusCode.API_EXCEPTION);
			} catch (RecordNotFoundException e) {
				logger.error(e.getMessage(), e);
				status.setCode(HomiStatusCode.RECORD_NOT_FOUND);
			}
		}
		status.write();
	}
	
	
	@RequestMapping(value="/option/consensus",method=RequestMethod.GET)
	public @ResponseBody void listConsensus(Integer topicId,int optionId,int offset,int limit,Integer gender,
			HttpServletRequest request,HttpServletResponse response){
		Integer userId = ServerHelper.getUserId(request);
		Status status = new Status(request,response);
		UserExtInfo selft = extInfoService.getUserExtInfoByUserId(userId);
		List<ConsensusUser> userList = null;
		Integer topicIdOfPass = topicId;
		if(gender!=null && gender>2) gender = null;
		if(gender!=null && gender<=0) gender = null;
		if(topicId==null){
			topicId = topicService.getTopicIdByOptionId(optionId);
		}
			
		if(topicId!=null){
			userList = topicService.listConsensusUser(topicId,gender,userId, optionId, offset, limit);
		}
		
		JSONObject result = new JSONObject();
		JSONArray list =  new JSONArray();
		int count = 0;
		
		if(userList!=null && !userList.isEmpty()){
			JSONObject element = null;
			double distance = -0d;
			ConsensusUser consensusUser = null;
			User user = null;
			UserExtInfo extInfo = null;
			Mood lastMood = null;
			Iterator<ConsensusUser> iter = userList.iterator();
			while(iter.hasNext()){
				consensusUser = iter.next();
				iter.remove();
				user = userService.getUserById(consensusUser.getUserId());
				extInfo = this.extInfoService.getUserExtInfoByUserId(user.getId());
				element = new JSONObject();
				element.accumulate("userId", consensusUser.getUserId());
				element.accumulate("distance", GeoUtil.getDistance(selft.getLongitude(), selft.getLatitude(), consensusUser.getLongitude(), consensusUser.getLatitude()));
				element.accumulate("avatar", HomiUtil.getRealUrl(user.getAvatar()));
				element.accumulate("gender", consensusUser.getGender());
				element.accumulate("nickName", user.getNickName());
				element.accumulate("mood", extInfo.getMood());
				lastMood = moodService.getMoodById(extInfo.getMoodId());
				element.accumulate("moodContent", lastMood.getContent());
				element.accumulate("lastLoginAt", extInfo.getLastLoginAt().getTime());
				boolean moodProtected = false;
				//可见度(1所有,2朋友,3私有)
				switch(lastMood.getVisibility()){
				case 2:
					boolean flag = friendService.isFriend(user.getId(), userId);
					if(!flag)
						flag = moodService.haveMoodViewPrivilege(userId, lastMood.getId());
					moodProtected = !flag;
					break;
				case 3:
					boolean haveViewPrivilege = moodService.haveMoodViewPrivilege(userId, lastMood.getId());
					moodProtected = !haveViewPrivilege;
					break;
				}
				element.accumulate("moodProtected", moodProtected);
				list.add(element);
			}
			iter = null;
			userList = null;
			if(list.size()>0)
				count = topicService.countConsensusUser(topicId,gender, userId, optionId);
		}
		result.accumulate("count", count);
		result.accumulate("list", list);
		status.setResult(result);
		status.write();
	}
	
	@RequestMapping(value="/opinion/post",method=RequestMethod.POST)
	public @ResponseBody void postOpinion(HttpServletRequest request,HttpServletResponse response) 
			throws IOException{
		Status status = new Status(request,response);
		String content = IOUtil.getContent4InputStream(request.getInputStream());
		JSONObject json = JSONObject.fromObject(content);
		Integer userId = ServerHelper.getUserId(request);
		TopicOpinion opinion = (TopicOpinion) JSONObject.toBean(json,TopicOpinion.class);
		if(opinion.getContent()==null){
			status.setCode(HomiStatusCode.PARAM_ABSENT);
			status.write();
			return;
		}
		
		opinion.setContent(ServerHelper.filterSensitiveWord(opinion.getContent().trim()));
		if(opinion.getContent().length()>HomiConstants.MAX_WORD_OPINION){
			status.setCode(HomiStatusCode.CONTENT_LENGTH_LIMIT);
			status.write();
			return;
		}
		
		opinion.setReviewer(userId);
		topicService.postTopicOpinion(opinion);
		if(opinion.getId()==0) status.setCode(HomiStatusCode.API_EXCEPTION);
		status.setResult("{\"id\":"+opinion.getId()+"}");
		status.write();
	}
	
	@RequestMapping(value="/opinion/delete",method=RequestMethod.GET)
	public @ResponseBody void deleteOpinion(int topicId,long id,HttpServletRequest request,HttpServletResponse response) 
			throws IOException{
		Integer reviewer = ServerHelper.getUserId(request);
		Status status = new Status(request,response);
		int rows = topicService.deleteOpinion(reviewer, topicId,id);
		if(rows==0) status.setCode(HomiStatusCode.API_EXCEPTION);
		status.write();
	}
	
	@RequestMapping(value="/opinion/get",method=RequestMethod.GET)
	public @ResponseBody void getOpinion(long id,HttpServletRequest request,HttpServletResponse response)
			throws IOException{
		TopicOpinion opinion = topicService.getTopicOpinionById(id);
		JSONObject result = null;
		Status status = new Status(request,response);
		if(opinion!=null){
			User reviewer = userService.getUserById(opinion.getReviewer());
			result = JSONObject.fromObject(opinion);
			result.put("createAt", opinion.getCreateAt().getTime());
			result.accumulate("reviewerNickName", reviewer==null?"无名":reviewer.getNickName());
			result.accumulate("reviewerAvatar", reviewer==null?"":HomiUtil.getRealUrl(reviewer.getAvatar()));
			status.setResult(result);
		}else{
			status.setCode(HomiStatusCode.RECORD_NOT_FOUND);
		}
		status.write();
	}
	
	@RequestMapping(value="/opinion/like",method=RequestMethod.POST)
	public @ResponseBody void likeOpinion(HttpServletRequest request,HttpServletResponse response)
			throws IOException{
		String content = IOUtil.getContent4InputStream(request.getInputStream());
		JSONObject json = JSONObject.fromObject(content);
		JSONObject result = null;
		Status status = new Status(request,response);
		if(json.containsKey("id")){
			int rows = topicService.likeOpinion(json.getLong("id"));
			if(rows==0) status.setCode(HomiStatusCode.RECORD_NOT_FOUND);
		}else{
			status.setCode(HomiStatusCode.PARAM_ABSENT);
		}
		status.write();
	}
	
	@RequestMapping(value="/opinion/list",method=RequestMethod.GET)
	public @ResponseBody void listOpinion(long idx,int topicId,int limit,
			HttpServletRequest request,HttpServletResponse response)
			throws IOException{
		List<TopicOpinion> list = topicService.listTopicOpinion(topicId, idx, limit);
		JSONArray result = new JSONArray();
		JSONObject json = null;
		User reviewer = null;
		TopicOpinion opinion = null;
		Iterator<TopicOpinion> iter = list.iterator();
		List<Review> reviewList = null;
		JSONArray reviewArray = null;
		JSONObject reviewJson = null;
		User receiver = null;
		while(iter.hasNext()){
			opinion = iter.next();
			iter.remove();
			reviewer = userService.getUserById(opinion.getReviewer());
			json = JSONObject.fromObject(opinion);
			json.accumulate("reviewerGender", reviewer.getGender());
			json.accumulate("reviewerNickName", reviewer.getNickName());
			json.accumulate("reviewerAvatar", HomiUtil.getRealUrl(reviewer.getAvatar()));
			json.put("createAt", opinion.getCreateAt().getTime());
			json.put("idx", opinion.getIdx()+"");
			reviewList = topicService.listReview(opinion.getId(), 0, 2);
			reviewArray = new JSONArray();
			
			for(Review review : reviewList){
				reviewer = userService.getUserById(review.getReviewer());
				receiver = userService.getUserById(review.getReceiver());
				reviewJson = JSONObject.fromObject(review);
				reviewJson.remove("tableName");
				reviewJson.put("receiverNickName", receiver==null?"无名":receiver.getNickName());
				reviewJson.put("reviewerNickName", reviewer==null?"无名":reviewer.getNickName());
				reviewJson.put("reviewerAvatar", reviewer==null?"":HomiUtil.getRealUrl(reviewer.getAvatar()));
				reviewJson.put("createAt", review.getCreateAt().getTime());
				reviewArray.add(reviewJson);
			}
			json.accumulate("reviewList", reviewArray);
			result.add(json);
		}
		iter = null;
		list = null;
		Status status = new Status(request,response);
		status.setResult(result);
		status.write();
	}
	
	@RequestMapping(value="/opinion/comment/post",method=RequestMethod.POST)
	public @ResponseBody void postOpinionComment(HttpServletRequest request,HttpServletResponse response) 
			throws IOException{
		super.postComment(COMMENT.TOPIC_OPINION, request, response);
	}
	
	@RequestMapping(value="/opinion/comment/delete",method=RequestMethod.GET)
	public @ResponseBody void deleteComment(long id,long parentId,HttpServletRequest request,HttpServletResponse response) 
			throws IOException{
		super.deleteComment(COMMENT.TOPIC_OPINION, id, parentId,request, response);
	}
	
	@RequestMapping(value="/opinion/comment/admin/delete",method=RequestMethod.GET)
	public @ResponseBody void deleteCommentByAdmin(long id,long parentId,HttpServletRequest request,HttpServletResponse response) 
			throws IOException{
		super.deleteCommentByAdmin(COMMENT.TOPIC_OPINION, id, parentId,request, response);
	}
	
	@RequestMapping(value="/opinion/comment/list",method=RequestMethod.GET)
	public @ResponseBody void listOpinionComment(long idx,long targetId,int limit,HttpServletRequest request,HttpServletResponse response){
		super.listComment(COMMENT.TOPIC_OPINION,idx, targetId, limit, request, response);
	}
	
	@RequestMapping(value="/opinion/comment/reply/post",method=RequestMethod.POST)
	public @ResponseBody void postReply(HttpServletRequest request,HttpServletResponse response) 
			throws IOException{
		super.postReply(REPLY.TOPIC_OPINION_COMMENT, request, response);
	}
	
	@RequestMapping(value="/opinion/comment/reply/delete",method=RequestMethod.GET)
	public @ResponseBody void deleteReply(long id,long parentId,HttpServletRequest request,HttpServletResponse response) 
			throws IOException{
		super.deleteReply(REPLY.TOPIC_OPINION_COMMENT,id, parentId,request, response);
	}
	
	@RequestMapping(value="/opinion/comment/reply/admin/delete",method=RequestMethod.GET)
	public @ResponseBody void deleteReplyByAdmin(long id,long parentId,HttpServletRequest request,HttpServletResponse response) 
			throws IOException{
		super.deleteReplyByAdmin(REPLY.TOPIC_OPINION_COMMENT,id, parentId,request, response);
	}
	
	@RequestMapping(value="/opinion/comment/reply/list",method=RequestMethod.GET)
	public @ResponseBody void listReply(long idx,long targetId,int limit,HttpServletRequest request,HttpServletResponse response){
		super.listReply(REPLY.TOPIC_OPINION_COMMENT, idx,targetId, limit, request, response);
	}
	
	@RequestMapping(value="/opinion/review/post",method=RequestMethod.POST)
	public @ResponseBody void review(HttpServletRequest request,
			HttpServletResponse response) {
		super.review(this.topicService, request, response);
	}

	@RequestMapping(value="/opinion/review/delete",method=RequestMethod.POST)
	public @ResponseBody void deleteReview(HttpServletRequest request,HttpServletResponse response) {
		super.deleteReview(this.topicService, request, response);
	}

	@RequestMapping(value="/opinion/review/list",method=RequestMethod.GET)
	public @ResponseBody void listReview(long eventId, int offset,
			int limit, HttpServletRequest request, HttpServletResponse response) {
		super.listReview(this.topicService, eventId, offset, limit, request, response);
	}
	
	@RequestMapping(value="/anonymous",method=RequestMethod.POST)
	public @ResponseBody void anonymous(HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		String content = IOUtil.getContent4InputStream(request.getInputStream());
		JSONObject json = JSONObject.fromObject(content);
		int succ = topicService.anonymousTopic(ServerHelper.getUserId(request), json.getInt("id"));
		Status status = new Status(request,response);
		if(succ==0) status.setCode(HomiStatusCode.API_EXCEPTION);
		status.write();
	}
}
